package one.stand.service.impl;

import com.alibaba.fastjson.JSON;
import one.stand.model.ResultModel;
import one.stand.model.ShareRecordModel;
import one.stand.model.UserModel;
import one.stand.request.AddShareCountRequest;
import one.stand.request.CreateShareRecordRequest;
import one.stand.request.statistics.BeginAndEndDateWrapper;
import one.stand.request.statistics.share.ShareTopNRequest;
import one.stand.request.statistics.share.ShareTypeDetailsStatisticsRequest;
import one.stand.request.statistics.share.SituationShareStatisticsRequest;
import one.stand.response.statistics.share.*;
import one.stand.service.BaseService;
import one.stand.service.ShareRecordService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.text.NumberFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by renz on 2019/10/23 23:40
 */
@Service
@Transactional
public class ShareRecordServiceImpl extends BaseService implements ShareRecordService {

    @Override
    public ResultModel<Integer> addShareRecord(CreateShareRecordRequest request) {
        log.info("添加分享记录:{}", JSON.toJSONString(request));
        if (request == null) {
            return ResultModel.checkParamFail("请求参数为空");
        }
        if (request.getUserId() == null) {
            return ResultModel.checkParamFail("添加分享记录的分享者id不能为空");
        }
        if (request.getCompanyId() == null) {
            log.error("分享的企业不能为空");
            return ResultModel.checkParamFail();
        }
        if (request.getShareType() == null) {
            log.error("分享类型不能为空");
            return ResultModel.checkParamFail();
        }

        UserModel user = userMapper.selectByPrimaryKey(request.getUserId());

        ShareRecordModel model = new ShareRecordModel();
        BeanUtils.copyProperties(request, model);
        model.setGender(user.getGender());
        model.setCreateTime(currentDate());
        int num = shareRecordMapper.insertReturningId(model);

        if (num > 0) {
            return ResultModel.success(model.getRecordId());
        }
        return ResultModel.fail("增加分享记录失败");
    }

    @Override
    public ResultModel<SituationShareStatisticsResponse> situationStatistics(SituationShareStatisticsRequest request) {
        BeginAndEndDateWrapper beginAndEndDateWrap = BeginAndEndDateWrapper.build(request.getTimeType());
        String beginDate = beginAndEndDateWrap.getBeginDate();
        String endDate = beginAndEndDateWrap.getEndDate();

        SituationShareStatisticsResponse response = new SituationShareStatisticsResponse();

        ShareUserAndCountStatistics shareUserAndCountStatistics = shareRecordMapper.shareUserAndCountStatistics(request.getCompanyId(), beginDate, endDate);
        response.setShareUserAndCountStatistics(shareUserAndCountStatistics);
        List<ShareTypeStatistics> shareTypeStatistics = shareRecordMapper.shareTypeStatistics(request.getCompanyId(), beginDate, endDate);
        // 默认填充类型值
        Map<Integer, ShareTypeStatistics> map = new HashMap<>();
        map.put(1, new ShareTypeStatistics(1, 0));
        map.put(2, new ShareTypeStatistics(2, 0));
        map.put(3, new ShareTypeStatistics(3, 0));
        map.put(4, new ShareTypeStatistics(4, 0));
        shareTypeStatistics.forEach(s -> map.put(s.getShareType(), s));
        response.setShareTypeStatistics(new ArrayList<>(map.values()));
        log.info("分享类型统计结果: {}", JSON.toJSONString(response.getShareTypeStatistics()));
        List<ShareGenderStatistics> shareGenderStatistics = shareRecordMapper.shareGenderStatistics(request.getCompanyId(), beginDate, endDate);
        if (!shareGenderStatistics.isEmpty()) {
            Float total;
            Float man = 0f;
            Float woman = 0f;
            Float notKnow = 0f;
            for (ShareGenderStatistics s : shareGenderStatistics) {
                switch (s.getGender()) {
                case 0:
                    notKnow = Float.valueOf(s.getCount());
                    break;
                case 1:
                    man = Float.valueOf(s.getCount());
                    break;
                case 2:
                    woman = Float.valueOf(s.getCount());
                    break;
                }
            }
            NumberFormat numberFormat = NumberFormat.getInstance();
            numberFormat.setMaximumFractionDigits(2);
            total = (man + woman + notKnow) == 0 ? 1 : (man + woman + notKnow);
            response.setMan(numberFormat.format((man / total) * 100) + "%");
            response.setWoman(numberFormat.format((woman / total) * 100) + "%");
            response.setNotKnow(numberFormat.format((notKnow / total) * 100) + "%");
        }

        return ResultModel.success(response);
    }

    @Override
    public ResultModel<List<ShareUserTopNResponse>> topN(ShareTopNRequest request) {
        BeginAndEndDateWrapper beginAndEndDateWrap = BeginAndEndDateWrapper.build(request.getTimeType());
        String beginDate = beginAndEndDateWrap.getBeginDate();
        String endDate = beginAndEndDateWrap.getEndDate();
        List<ShareUserTopNResponse> shareUserTopNResponses = shareRecordMapper.topN(request.getCompanyId(), request.getTopN(), beginDate, endDate)
                                                                              .stream()
                                                                              .peek(s -> s.setNickName(new String(Base64.getDecoder().decode(s.getNickName()))))
                                                                              .collect(Collectors.toList());
        return ResultModel.success(shareUserTopNResponses);
    }

    @Override
    public ResultModel<List<ShareTypeDetailsStatisticsRepository>> shareTypeDetailsStatistics(ShareTypeDetailsStatisticsRequest request) {
        BeginAndEndDateWrapper beginAndEndDateWrap = BeginAndEndDateWrapper.build(request.getTimeType());
        String beginDate = beginAndEndDateWrap.getBeginDate();
        String endDate = beginAndEndDateWrap.getEndDate();
        List<ShareTypeDetailsStatisticsRepository> result = shareRecordMapper.shareTypeDetailsStatistics(request.getCompanyId(), request.getShareUserId(),
                                                                                                         beginDate, endDate);
        return ResultModel.success(result);
    }

    @Override
    public ResultModel<Boolean> addOpenShareCount(AddShareCountRequest request) {
        log.info("添加分享打开次数请求:{}", JSON.toJSONString(request));
        if (request.getShareRecordId() == null && StringUtils.isEmpty(request.getUuid())) {
            return ResultModel.checkParamFail("增加打开分享次数 uuid 或者分享id 不能同时为空");
        }
        int num = 0;
        // 保留通过id进行添加打开次数，兼容老接口
        if (!StringUtils.isEmpty(request.getUuid())) {
            num = shareRecordMapper.addShareOpenCount(request.getUuid(), new Date());
        } else {
            num = shareRecordMapper.addShareOpenCountById(request.getShareRecordId(), new Date());
        }
        if (num > 0) {
            return ResultModel.success(true);
        }
        return ResultModel.fail("增加打开分享次数失败");
    }

}
